package cn.wwcyc.controller;

import cn.wwcyc.domain.*;
import cn.wwcyc.exception.WWExceptionEnum;
import cn.wwcyc.mapper.TjMenugroupMapper;
import cn.wwcyc.mapper.UserMapper;
import cn.wwcyc.service.TjDwService;
import cn.wwcyc.service.UserService;
import cn.wwcyc.utils.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/user")

public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    TjMenugroupMapper tjMenugroupMapper;
    @Autowired
    TjDwService tjDwService;


    private String getIp(HttpServletRequest request) {
        String ip = null;
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            String xff = request.getHeader("x-forwarded-for");
            if (xff != null && xff.length() != 0) {
                ip = xff.split(",")[0];
            }
        }
        return ip;
    }

    @PostMapping("/login")
    public R<UserVo> longin(@RequestBody User user, HttpServletRequest request, HttpSession session) {

        User u;
        UserVo uv = new UserVo();
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("username", user.getUsername());
        qw.eq("password", user.getPassword());
//        try {
        u = userService.getOne(qw);
        if (u != null) {
            BeanUtils.copyProperties(u, uv);
            String token = JWTUtil.getToken(uv, 1000 * 60 * 60 * 24);//有效期30天
            uv.setToken(token);
            //这里userMapper.getUserRoleMenuVo只可能获得一个，因为有username参数，而用户名唯一
            List<UserRoleMenuVo> userList = userMapper.getUserRoleMenuVo(user.getUsername(), null);
            for (UserRoleMenuVo userRoleMenuVo : userList) {
                if (userRoleMenuVo.getId() == uv.getId()) {
                    uv.setMenuList(userRoleMenuVo.getMenuList());
                }
            }
            //超级用户权限检查,非超级用户去除超级菜单项,这里边遍历边删除，用普通for循环来避免concurrentModification异常
            if (uv.getSuperadmin() == null || (uv.getSuperadmin() != null && !uv.getSuperadmin())) {
                for (int i = uv.getMenuList().size() - 1; i >= 0; i--) {
                    Menu menu = uv.getMenuList().get(i);
                    if (menu.getNeedsuper() != null && menu.getNeedsuper()) {
                        uv.getMenuList().remove(menu);
                    }
                }
            }
//下面的代码会出现concorrentModificationException
//            if ((uv.getSuperadmin() == null) || (uv.getSuperadmin() !=null && !uv.getSuperadmin())) {
//                for (Menu menu : uv.getMenuList()) {
//                    if (menu.getNeedsuper() != null && menu.getNeedsuper()) {
//                        uv.getMenuList().remove(menu);
//                    }
//                }
//            }

            List<Menu> menuTreeList = MenuListtoTree(uv.getMenuList());
            uv.setMenuTree(menuTreeList);
            List<TjMenugroup> menuTreeGroupList = MenuTreeListtoGroupList(uv, menuTreeList);
            uv.setMenuTreeGroupList(menuTreeGroupList);
            //jwt无法通过session获得ip！！下面代码暂时没用
//                String loginip = getIp(request);
//                System.out.println("登录ip:" + loginip);
//                session.setAttribute("loginip", loginip);

            return R.success(uv);
        } else {
            return R.error(WWExceptionEnum.ERROR_USERNAME_PASSWORD);
        }
//        } catch (Exception e) {
////            WWExceptionEnum wwe = new WWExceptionEnum;
//            System.out.println(e.getMessage());
//            return R.error(WWExceptionEnum.SYSTEM_ERROR);
////            return null;
//        }
    }

    //将菜单树列表按照group进行分组
    private List<TjMenugroup> MenuTreeListtoGroupList(UserVo uv, List<Menu> menuTreeList) {

        List<TjMenugroup> menugroupList = tjMenugroupMapper.selectListByuser(uv.getId());
//        //若一个用户拥有2个角色，这2个角色拥有同一个菜单组，则menugroupList里面会有2个相同的菜单组
//        List<TjMenugroup> menugroupList2 = new ArrayList<>();
//        if (menugroupList != null && menugroupList.size() > 0) {
//            for (TjMenugroup menugroup : menugroupList) {
//                boolean flag = true;
//                for (TjMenugroup menugroup2 : menugroupList2) {
//                    if (menugroup.getId().equals(menugroup2.getId())) {
//                        flag = false;
//                        break;
//                    }
//                }
//                if (flag) {
//                    menugroupList2.add(menugroup);
//                }
//            }
//        }
        if (menuTreeList != null && menuTreeList.size() > 0) {
            for (TjMenugroup menugroup : menugroupList) {
                if (menugroup.getMenuTreeList() == null)
                    menugroup.setMenuTreeList(new ArrayList<>());
                for (Menu menu : menuTreeList) {
                    if (menugroup.getId().equals(menu.getGroupid())) {
//                        System.out.println("-----------------------" + menu.getGroupid());
                        menugroup.getMenuTreeList().add(menu);
                    }

                }
            }
            return menugroupList;
        }
        return null;
    }


    @GetMapping("/changePassword")
    public R changePassword(@RequestParam Long userId, @RequestParam String oldpassword, @RequestParam String newpassword) {
        System.out.println(userId);
        System.out.println(oldpassword);
        userService.changePassword(userId, oldpassword, newpassword);
        return R.success();

    }

    //将菜单列表转换为菜单树
    private List<Menu> MenuListtoTree(List<Menu> menuList) {
        List<Menu> menuTreeList = null;
        if (menuList != null && menuList.size() > 0) {
            menuTreeList = new ArrayList<>();
            for (Menu menu : menuList) {
                if (menu.getPid() == null) {
                    List<Menu> children = getMenuChildren(menu, menuList);
                    menu.setChildren(children);
                    menuTreeList.add(menu);
                }
            }
            menuTreeList.sort((o1, o2) -> {
                if (o1.getXh() == null)
                    return 1;
                return o1.getXh().compareTo(o2.getXh());
            });
            return menuTreeList;
        }
        return null;
    }

    private List<Menu> getMenuChildren(Menu menu, List<Menu> menuList) {
        List<Menu> children = null;
        if (menuList != null && menuList.size() > 0) {
            children = new ArrayList<>();
            for (Menu m : menuList) {
                if (m.getPid() == menu.getId()) {
                    children.add(m);
                }
            }
            for (Menu m : children) {
                List<Menu> grandson = getMenuChildren(m, menuList);
                m.setChildren(grandson);
            }
        }
        if (children != null) {
            children.sort((o1, o2) ->
            {
                if (o1.getXh() == null)
                    return 1;
                return o1.getXh().compareTo(o2.getXh());
            });
        }
        return children;
    }

    @GetMapping("/getpage")
    public R<IPage<User>> getpage(@RequestParam Integer pagenum, @RequestParam Integer pagesize) {
        IPage<User> page = new Page<>(pagenum, pagesize);
        page = userService.page(page);
        return R.success(page);
    }

    @PostMapping("/save")
    public R save(@RequestBody User user) {
        userService.save(user);
        return R.success();
    }

    @PostMapping("/savewithroles")
    public R savewithroles(@RequestBody UserVo user, HttpServletRequest request) {
        User currentUser = userService.getCurrentUser(request);
//        System.out.println(user);
        if(user.getDw() == null){
            user.setDw(currentUser.getDw());
        }
        userService.saveWithRoles(user);
        return R.success();
    }

    @PostMapping("/editwithroles")
    public R editwithroles(@RequestBody UserVo user) {
//        System.out.println(user);
        userService.editWithRoles(user);
        return R.success();
    }
    @PostMapping("/editwithroles2")
    public R editwithroles(@RequestBody UserDTO user) {
//        System.out.println(user);
        userService.editWithRoles(user);
        return R.success();
    }

    @PostMapping("/edit")
    public R edit(@RequestBody User user) {
//        System.out.println(user);
        //原始的update不能处理roleid为空的情况！，这里自己写一个
        Integer i = userService.myUpdateById(user);
        return R.success(i);
    }

    @DeleteMapping
    public R del(Integer id) {
//        userService.save(user);
        userService.removeById(id);
        return R.success();
    }

    @GetMapping("/getpage1")
    public R<IPage<UserRoleMenuVo>> getpage1(
            @RequestParam Integer pagenum,
            @RequestParam Integer pagesize,
            @RequestParam(required = false) Long dw,
            @RequestParam(required = false) String username,
            HttpServletRequest request
    ) {
        User user = userService.getCurrentUser(request);
        if (dw == null)
            dw = user.getDw();

        TjDw tjDw = null;
        if (dw != null) {
            tjDw = tjDwService.getDwTreeById(dw);
        }
        List<TjDw> dwlist = new ArrayList<>();
        dwlist = tjDwService.DwTreeToList(dwlist, tjDw);
        List<Long> dwIdList = new ArrayList<>();
        for (TjDw tjDw1 : dwlist) {
            dwIdList.add(tjDw1.getId());
        }

        IPage<UserRoleMenuVo> page = new Page<>(pagenum, pagesize);
        page = userService.getUserRoleMenuVo(page, username, dwIdList);
        return R.success(page);
    }
    @RequestMapping("/checkSameUserName")
    public R checkSameUserName(@RequestParam String userName){
        if(!userService.checkSameUserName(userName)){
            return R.success();
        }else{
            return R.error(WWExceptionEnum.USERNAME_EXIST);
        }
    }
    @RequestMapping("/checkEditSameUserName")
    public R checkEditSameUserName(@RequestParam Long id, @RequestParam String userName){
        if(!userService.checkEditSameUserName(id, userName)){
            return R.success();
        }else{
            return R.error(WWExceptionEnum.USERNAME_EXIST);
        }
    }
}
